Skip to main content

API Authentication

This article explains how to authenticate with the Cyberhaven API using Python code examples.

Overview

Cyberhaven uses a two-step token-based authentication system:

  1. API Key: Long-lived credential (up to 1 year) created in the Console
  2. Access Token: Short-lived token (15 minutes) used for API requests

Why Authentication is Required

  • Access Control: Only authorized users can access your data
  • Security: Protects sensitive information like incidents and events
  • Audit Trail: Tracks API usage for compliance
  • Rate Limiting: Prevents abuse (max 5 concurrent requests per endpoint)

Creating an API Key

  1. Navigate to Settings > Users & API Keys in the Cyberhaven Console
  2. Click API Keys tab → New API Key
  3. Set name, role (e.g., "API Admin"), and validity period
  4. Important: Copy the key immediately - it won't be shown again

Python Implementation

Basic Authentication

import requests
from datetime import datetime, timedelta

class CyberhavenAPI:
def __init__(self, api_key, tenant):
# Store credentials and initialize token tracking
self.api_key = api_key
self.base_url = f"https://{tenant}"
self.access_token = None
self.token_expires = None

def get_access_token(self):
"""Exchange API key for a 15-minute access token"""
url = f"{self.base_url}/v2/auth/token/access"
payload = {"api_key": self.api_key}

response = requests.post(url, json=payload)
response.raise_for_status()

data = response.json()
self.access_token = data['access_token']
# Set expiry to 14 minutes to refresh before actual expiry
self.token_expires = datetime.now() + timedelta(minutes=14)

return self.access_token

def ensure_valid_token(self):
"""Check if token exists and hasn't expired, refresh if needed"""
if not self.access_token or datetime.now() >= self.token_expires:
self.get_access_token()

def make_request(self, method, endpoint, data=None):
"""Make authenticated API request with automatic token refresh"""
# Ensure we have a valid token before making the request
self.ensure_valid_token()

url = f"{self.base_url}{endpoint}"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}

response = requests.request(method, url, headers=headers, json=data)
response.raise_for_status()
return response.json()

# Usage example
api = CyberhavenAPI(
api_key="your_api_key_here",
tenant="your-tenant-name.cyberhaven.io"
)

# Get incidents - token will be automatically obtained
incidents = api.make_request("GET", "/v2/incidents")
print(f"Found {len(incidents.get('incidents', []))} incidents")

curl Example

# Step 1: Get access token
API_KEY="your_api_key_here"
TENANT="your-tenant-name.cyberhaven.io"

ACCESS_TOKEN=$(curl -s -X POST \
"https://${TENANT}/v2/auth/token/access" \
-H "Content-Type: application/json" \
-d "{\"api_key\": \"${API_KEY}\"}" | \
jq -r '.access_token')

# Step 2: Use token for API calls
curl -X GET \
"https://${TENANT}/v2/incidents" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json"

Advanced Python with Error Handling

import requests
import time
from datetime import datetime, timedelta

class CyberhavenAPI:
def __init__(self, api_key, tenant, max_retries=3):
self.api_key = api_key
self.base_url = f"https://{tenant}"
self.access_token = None
self.token_expires = None
self.max_retries = max_retries

def get_access_token(self):
"""Get access token with error handling"""
url = f"{self.base_url}/v2/auth/token/access"
payload = {"api_key": self.api_key}

try:
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()

data = response.json()
self.access_token = data['access_token']
self.token_expires = datetime.now() + timedelta(minutes=14)

return self.access_token
except requests.exceptions.RequestException as e:
raise Exception(f"Authentication failed: {e}")

def make_request(self, method, endpoint, data=None):
"""Make request with retry logic and automatic token refresh"""
for attempt in range(self.max_retries):
try:
# Refresh token if needed
if not self.access_token or datetime.now() >= self.token_expires:
self.get_access_token()

url = f"{self.base_url}{endpoint}"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}

response = requests.request(method, url, headers=headers, json=data, timeout=60)

# Handle token expiry
if response.status_code == 401:
self.access_token = None # Force token refresh
continue

response.raise_for_status()
return response.json()

except requests.exceptions.RequestException as e:
if attempt == self.max_retries - 1:
raise Exception(f"Request failed after {self.max_retries} attempts: {e}")
time.sleep(2 ** attempt) # Exponential backoff

# Usage with error handling
try:
api = CyberhavenAPI("your_api_key", "your-tenant.cyberhaven.io")
incidents = api.make_request("GET", "/v2/incidents")
print(f"Success: {len(incidents.get('incidents', []))} incidents")
except Exception as e:
print(f"Error: {e}")

Key Points

  • Token Expiry: Access tokens expire in 15 minutes
  • Rate Limits: Maximum 5 concurrent requests per endpoint
  • Security: Store API keys securely (environment variables)
  • Error Handling: Always handle 401 (unauthorized) and 429 (rate limit) responses
  • Testing: Use the API explorer in Administration > API Specification